
import fetch from './fetch'
import localStorage from './localStorage'

const makeFetch = (method) => {
    return (baseApi, paramsOption = {}, defineArgs) => {
        return function (success) {
            let api = baseApi
            let params = {}
            let context = Object.assign({}, paramsOption)
            let reqParams = {}
            if (defineArgs) {
                if (typeof defineArgs === 'string') {
                    defineArgs = defineArgs.split(/\s*,\s*/)
                }
                let inputArgs = [...arguments].slice(1) // 第一个参数为callback 
                let localArgs = {}
                let pathArgs = {}
                defineArgs.forEach((argName, i) => {
                    let argValue = inputArgs[i]
                    if (argName.indexOf('$') === 0) { // 用于生成params的变量，可以从paramsOption中读取默认值
                        localArgs[argName] = argValue == null ? paramsOption[argName] : argValue
                    } else if (argName.indexOf(':') === 0) { // 用于替换api路径的变量
                        pathArgs[argName] = argValue
                    } else { // 请求变量
                        reqParams[argName] = argValue
                    }
                })

                for (let key in pathArgs) { // 替换api变量
                    api = api.replace(RegExp(key + '\\b'), `${pathArgs[key]}`)
                }

                Object.assign(context, reqParams, localArgs) // 创建参数运行上下文
            }


            for (let key in paramsOption) {
                let value = paramsOption[key]
                if (typeof value === 'function') { //函数则执行运算使用返回值
                    params[key] = value(context)
                } else if (key.indexOf('$') !== 0) {
                    params[key] = value
                }
            }
            for (let key in reqParams) { // 合并请求参数
                if (reqParams[key] != null) {
                    params[key] = reqParams[key]
                }
            }

            if (success) {
                fetch(api, params, method).then(success)
            } else {
                return fetch(api, params, method)
            }
        }
    }
}

const fetchGet = makeFetch('get')
const fetchPost = makeFetch('post')


export const getPosition = (success) => {
    success(localStorage('position') || null)
}
export const setPosition = (success, data) => {
    localStorage('position', data)
    success()
}

export const getDefaultCity = fetchGet('/v1/cities', { type: 'guess' })
export const getHotCitys = fetchGet('/v1/cities', { type: 'hot' })
export const getAllCitys = fetchGet('/v1/cities', { type: 'group' })
export const getSearchAddressHistory = (success) => {
    success(localStorage('searchAddressHistory') || [])
}
export const setSearchAddressHistory = (data) => {
    localStorage('searchAddressHistory', data)
}
export const clearAddressHistory = () => {
    localStorage('searchAddressHistory', [])
}
export const getSearchAddress = fetchGet('/v1/pois', { type: 'search' }, 'city_id, keyword')
export const getCityName = fetchGet('/v1/cities/:cityid', null, ':cityid')
export const getAddressInfo = fetchGet('/v2/pois/:addressId', null, ':addressId')
export const getFoodTypes = fetchGet('/v2/index_entry', {
    group_type: 1,
    'flags[]': 'F',
    geohash: ($position) => [$position.latitude, $position.longitude].join(',')
}, '$position')
export const getShopList = fetchGet('/shopping/restaurants', {
    $page: 1,
    restaurant_category_id: '',
    $restaurant_category_ids: '',
    order_by: '',
    $delivery_mode: '',
    $support_ids: [],

    latitude: ({ $position }) => $position.latitude,
    longitude: ({ $position }) => $position.longitude,
    offset: ({ limit, $page }) => limit * ($page - 1),
    limit: 16,
    keyword: '',
    'extras[]': 'activities',
    'restaurant_category_ids[]': ({ $restaurant_category_ids }) => $restaurant_category_ids,
    'delivery_mode[]': ({ $delivery_mode, $support_ids }) => [$delivery_mode, ...$support_ids.map(id => 'support_ids[]=' + id)].join('&')
}, ['$position', '$page', 'restaurant_category_id', '$restaurant_category_ids', 'order_by', '$delivery_mode', '$support_ids'])

export const getFoodCategorys = fetchGet('/shopping/v2/restaurant/category', {
    latitude: ({ $position }) => $position.latitude,
    longitude: ({ $position }) => $position.longitude
}, '$position')

export const getFoodDeliveries = fetchGet('/shopping/v1/restaurants/delivery_modes', {
    latitude: ({ $position }) => $position.latitude,
    longitude: ({ $position }) => $position.longitude,
    kw: ''
}, '$position')

export const getFoodSupports = fetchGet('/shopping/v1/restaurants/activity_attributes', {
    latitude: ({ $position }) => $position.latitude,
    longitude: ({ $position }) => $position.longitude,
    kw: ''
}, '$position');




export const saveUserInfo = (success, data) => {
    let userInfo = { value: data }
    localStorage('userInfo', userInfo)
    success(data)
}

export const getUserInfo = (success) => {
    let userInfo = localStorage('userInfo')
    if (userInfo) {
        success(userInfo.value)
    } else {
        success(null)
    }
}

export const getVcodeImg = fetchPost('/v1/captchas')

export const accountLogin = fetchPost('/v2/login', null, 'username, password, captcha_code')

export const logout = (success) => {
    fetch('v2/signout').then(() => {
        localStorage('userInfo', null)
        success()
    })
}


export const getShopInfo = fetchGet('/shopping/restaurant/:shopId', null, ':shopId')

export const getShopFoodCategories = fetchGet('/shopping/v2/menu', null, 'restaurant_id')


export const setOrders = (success, orders) => {
    localStorage('orders', orders)
    success && success()
}

export const getOrders = (success) => {
    success(localStorage('orders') || {})
}